package i18n

import (
	"encoding/json"
	"errors"
	"fmt"
	"math"
	"sort"
	"strconv"
	"strings"
	"unicode"
	"unsafe"

	"github.com/pelletier/go-toml/v2"
	"gopkg.in/yaml.v3"
)

// MapAnyToMessages 将 map[string]any 格式的嵌套消息文本 转换为 FlatMapMessages 类型的消息数据
//   - data: map[string]any 多级分组嵌套格式消息数据
//   - return: FlatMapMessages 扁平化消息数据类型(一维平铺的的消息数据)
func MapAnyToMessages(data map[string]any) (FlatMapMessages, error) {
	if data == nil {
		return nil, ErrParseMessageNil
	}
	if len(data) == 0 {
		return nil, ErrParseMessageEmpty
	}
	messages := make(FlatMapMessages)
	if err := _mapAnyPushToMessage(messages, data, ""); err != nil {
		return nil, err
	}
	return messages, nil
}
func _mapAnySlicePushToMessage(mapMessage FlatMapMessages, data []any, key string) error {
	if len(data) == 0 {
		return ErrParseMessageEmptyPlural
	}
	// 转为[][]string
	vs := make([][]string, len(data))
	for i, v1 := range data {
		switch v2 := v1.(type) {
		case []string:
			vs[i] = v2
		case []any:
			vs[i] = make([]string, len(v2))
			for j, v3 := range v2 {
				if v4s, ok := v3.(string); ok {
					vs[i][j] = v4s
				} else {
					return ErrParseMessageInvalidPlural
				}
			}
		default:
			return ErrParseMessageInvalidPlural
		}
	}
	if msg, err := ParsePluralMessage(vs); err == nil {
		mapMessage[key] = &Message{Plural: msg}
	} else {
		return err
	}
	return nil
}
func _mapAnyAnySlicePushToMessage(mapMessage FlatMapMessages, data [][]any, key string) error {
	if len(data) == 0 {
		return ErrParseMessageEmptyPlural
	}
	// 转为[][]string
	vs := make([][]string, len(data))
	for i, v1 := range data {
		if len(v1) == 0 {
			continue
		}
		vs[i] = make([]string, len(v1))
		for j, v2 := range v1 {
			if v2s, ok := v2.(string); ok {
				vs[i][j] = v2s
			} else {
				return ErrParseMessageInvalidPlural
			}
		}
	}
	if msg, err := ParsePluralMessage(vs); err == nil {
		mapMessage[key] = &Message{Plural: msg}
	} else {
		return err
	}
	return nil
}

func _mapAnyPushToMessage(mapMessage FlatMapMessages, data map[string]any, preKey string) error {
	if len(data) == 0 {
		return nil
	}
	var fullKey string
	for k, v := range data {
		key, err := ParseKey(k)
		if err != nil {
			return err
		}
		if key == "" {
			return ErrParseKeyEmpty
		}
		switch key {
		case "_text":
			vs, ok := v.(string)
			if !ok {
				return ErrParseMessageInvalidText
			}
			mapMessage[preKey] = &Message{Text: vs}
			continue
		case "_plural":
			switch vs := v.(type) {
			default:
				return ErrParseMessageInvalidPlural
			case []any:
				if len(vs) == 0 {
					continue
				}
				if err := _mapAnySlicePushToMessage(mapMessage, vs, preKey); err != nil {
					return err
				}
			case [][]any:
				if len(vs) == 0 {
					continue
				}
				if err := _mapAnyAnySlicePushToMessage(mapMessage, vs, preKey); err != nil {
					return err
				}
			case [][]string:
				if len(vs) == 0 {
					continue
				}
				msg, err := ParsePluralMessage(vs)
				if err != nil {
					return err
				}
				mapMessage[preKey] = &Message{Plural: msg}
			}
			continue
		case "_group":
			if vs, ok := v.(map[string]any); ok {
				if len(vs) == 0 {
					continue
				}
				if err := _mapAnyPushToMessage(mapMessage, vs, preKey); err != nil {
					return err
				}
			} else if vs, ok := v.(map[string]string); ok {
				if len(vs) == 0 {
					continue
				}
				if err := _mapStringPushToMessage(mapMessage, vs, preKey); err != nil {
					return err
				}
			} else {
				return ErrParseMessageInvalidGroup
			}
			continue
		}
		if preKey == "" {
			fullKey = key
		} else {
			fullKey = preKey + "." + key
		}
		switch vs := v.(type) {
		default:
			return ErrParseMessageInvalidType
		case string:
			// 普通消息文本
			mapMessage[fullKey] = &Message{Text: vs}
		case []any:
			// 复数消息文本
			if len(vs) == 0 {
				continue
			}
			if err := _mapAnySlicePushToMessage(mapMessage, vs, fullKey); err != nil {
				return err
			}
		case [][]any:
			// 复数消息文本
			if len(vs) == 0 {
				continue
			}
			if err := _mapAnyAnySlicePushToMessage(mapMessage, vs, fullKey); err != nil {
				return err
			}
		case [][]string:
			// 复数消息文本
			if len(vs) == 0 {
				continue
			}
			if msg, err := ParsePluralMessage(vs); err == nil {
				mapMessage[fullKey] = &Message{Plural: msg}
			} else {
				return err
			}
		case map[string]any:
			if len(vs) == 0 {
				continue
			}
			if err := _mapAnyPushToMessage(mapMessage, vs, fullKey); err != nil {
				return err
			}
		case map[string]string:
			if len(vs) == 0 {
				continue
			}
			if err := _mapStringPushToMessage(mapMessage, vs, fullKey); err != nil {
				return err
			}
		}
	}
	return nil
}
func _mapStringPushToMessage(mapMessage FlatMapMessages, data map[string]string, preKey string) error {
	if len(data) == 0 {
		return nil
	}
	var fullKey string
	for k, v := range data {
		key, err := ParseKey(k)
		if err != nil {
			return err
		}
		if key == "" {
			return ErrParseKeyEmpty
		}
		if preKey == "" {
			fullKey = key
		} else {
			fullKey = preKey + "." + key
		}
		switch key {
		case "_Text":
			if v == "" {
				return ErrParseMessageEmptyText
			}
			mapMessage[fullKey] = &Message{Text: v}
		default:
			if v == "" {
				return ErrParseMessageTypesBeSet
			}
			mapMessage[fullKey] = &Message{Text: v}
		}
	}
	return nil
}

// MessagesToMapAny 将 FlatMapMessages 格式的平铺消息转换为 map[string]any 多级分组嵌套格式消息文本
//   - data: FlatMapMessages 扁平化消息数据类型(一维平铺的的消息数据)
//   - return: map[string]any 多级分组嵌套格式消息数据
func MessagesToMapAny(data FlatMapMessages) (map[string]any, error) {
	if data == nil {
		return nil, ErrParseMessageNil
	}
	if len(data) == 0 {
		return nil, ErrParseMessageEmpty
	}
	ms := make(map[string]any)

	for k, msg := range data {
		key, err := ParseKey(k)
		if err != nil {
			return nil, err
		}
		if key == "" {
			return nil, ErrParseKeyEmpty
		}
		if msg == nil {
			return nil, ErrParseMessageNil
		}
		curMap := ms
		keys := strings.Split(key, ".")
		if len(keys) > 1 {
			for i, subKey := range keys {
				// 最后一个key，终止遍历, 后续直接进行赋值
				if i >= len(keys)-1 {
					key = subKey
					break
				}
				// 如果当前key不存在，则创建map[string]any类型的子Map
				if _, ok := curMap[subKey]; !ok {
					nextMap := map[string]any{}
					curMap[subKey] = nextMap
					curMap = nextMap
					continue
				}
				// 如果当前key存在，检查其值类型：
				switch curVal := curMap[subKey].(type) {
				case map[string]any:
					curMap = curVal
				case [][]string:
					// 原来是 _Plural
					nextMap := map[string]any{
						"_plural": curVal,
					}
					curMap[subKey] = nextMap
					curMap = nextMap
				case string:
					// 原来是 _Text
					nextMap := map[string]any{
						"_text": curVal,
					}
					curMap[subKey] = nextMap
					curMap = nextMap
				default:
					return nil, fmt.Errorf("i18n.MessagesToMapAny: key[%s] subKey[%s] invalid element type %T", key, subKey, curVal)
				}
			}
		}
		// 不存在, 直接插入当前 key/Message 到 curMap
		if _, ok := curMap[key]; !ok {
			if msg.Text != "" {
				curMap[key] = msg.Text
			} else if msg.Plural != nil {
				curMap[key] = msg.Plural.ToStringSlices()
			}
			continue
		}
		// 存在, 更新当前key的节点值或类型
		switch curVal := curMap[key].(type) {
		case string:
			// 原来是 _text
			// 这里需要明确冲突处理
			if msg.Text != "" {
				// 更新为 _text
				curMap[key] = msg.Text
			} else if msg.Plural != nil {
				// 更新为 _plural
				curMap[key] = msg.Plural.ToStringSlices()
			}
		case [][]string:
			// 原来是 _plural
			if msg.Text != "" {
				curMap[key] = msg.Text
			} else if msg.Plural != nil {
				curMap[key] = msg.Plural.ToStringSlices()
			}
		case map[string]any:
			// 原来是一个分组
			// 这里需要明确冲突处理
			if msg.Text != "" {
				curVal["_text"] = msg.Text
				delete(curVal, "_plural")
			} else if msg.Plural != nil {
				delete(curVal, "_text")
				curVal["_plural"] = msg.Plural.ToStringSlices()
			}
		default:
			return nil, ErrParseMessageInvalidType
		}
	}
	return ms, nil
}

// MessagesToBytes 将 FlatMapMessages 导出为指定文件格式的字节切片数据，用于文件导出使用
//   - data:  FlatMapMessages 扁平化消息数据类型(一维平铺的的消息数据)，通常为包含了同一种语言的全部消息数据
//   - format: 文件格式, 支持 json, toml, yaml, yml
func MessagesToBytes(data FlatMapMessages, format string) ([]byte, error) {
	if data == nil {
		return nil, errors.New("ExportMessagesToBytes: Messages data is nil")
	}
	if len(data) == 0 {
		return nil, errors.New("ExportMessagesToBytes: Messages data is empty")
	}
	dataMap, err := MessagesToMapAny(data)
	if err != nil {
		return nil, fmt.Errorf("ExportMessagesToBytes: MessagesToMapAny error, %s", err.Error())
	}
	format = strings.ToLower(strings.Trim(format, ". "))
	switch format {
	case "json":
		return json.MarshalIndent(dataMap, "", "\t")
	case "toml":
		return toml.Marshal(dataMap)
	case "yaml", "yml":
		return yaml.Marshal(dataMap)
	default:
		return nil, fmt.Errorf("ExportMessagesToBytes: format %s not supported", format)
	}
}

// PrintFlatMapMessages 格式化打印 FlatMapMessages 类型的消息数据为字符串，用于调试或查看数据结构
//   - data: FlatMapMessages  扁平化消息数据类型(一维平铺的的消息数据)
//   - return: string 格式化后的字符串
func PrintFlatMapMessages(data FlatMapMessages) string {
	if data == nil {
		return "PrintFlatMapMessages: data is nil"
	}
	if len(data) == 0 {
		return "PrintFlatMapMessages: data is empty"
	}
	build := new(strings.Builder)
	build.WriteString("PrintFlatMapMessages: \n")
	// 按Key排序后输出
	for _, k := range getSortedMapKeys(data) {
		_printFlatMapMessages(build, k, data[k])
	}
	return build.String()
}
func _printFlatMapMessages(build *strings.Builder, key string, msg *Message) {
	if msg == nil {
		return
	}
	index := strings.Count(key, ".")
	if index > 0 {
		build.WriteString(strings.Repeat("...", index))
	}
	build.WriteString(key)
	build.WriteString(" => ")
	if msg.Text != "" {
		build.WriteString(msg.Text)
	} else if msg.Plural != nil {
		build.WriteString("[")
		for i, text := range msg.Plural.ToStringSlices() {
			if i > 0 {
				build.WriteString(", ")
			}
			build.WriteByte('[')
			build.WriteRune('"')
			build.WriteString(text[0])
			build.WriteRune('"')
			build.WriteRune(',')
			build.WriteRune('"')
			build.WriteString(text[1])
			build.WriteRune('"')
			build.WriteString("]")
		}
		build.WriteString("]")
	}
	build.WriteRune('\n')
}

// PrintMapAnyMessages 格式化打印 map[string]any 类型的消息数据为字符串，用于调试或查看数据结构
//   - data: map[string]any 多级分组嵌套格式消息数据
//   - return: string 格式化后的字符串
func PrintMapAnyMessages(data map[string]any) string {
	if data == nil {
		return "PrintMapAnyMessages: data is nil"
	}
	if len(data) == 0 {
		return "PrintMapAnyMessages: data is empty"
	}
	build := new(strings.Builder)
	build.WriteString("PrintMapAnyMessages: \n")
	// 按Key排序后输出
	for _, k := range getSortedMapKeys(data) {
		_printMapAnyMessage(build, k, data[k], 0)
	}
	return build.String()
}
func _printMapAnyMessage(build *strings.Builder, key string, msg any, index int) {
	if msg == nil {
		return
	}
	if index > 0 {
		build.WriteString(strings.Repeat("...", index))
	}
	build.WriteString("\"")
	build.WriteString(key)
	build.WriteString("\"")
	build.WriteString(" => ")
	switch vs := msg.(type) {
	default:
		return
	case string:
		build.WriteString("\"")
		build.WriteString(vs)
		build.WriteString("\"")
		build.WriteRune('\n')
	case []any:
		// 测试是否能将[]any 转为 [][]string
		vss := make([][]string, len(vs))
		for i, v := range vs {
			switch vv := v.(type) {
			default:
				return
			case []string:
				vss[i] = vv
			case []any:
				vss[i] = make([]string, len(vv))
				for j, vvv := range vv {
					switch vvvv := vvv.(type) {
					case string:
						vss[i][j] = vvvv
					}
				}
			}
		}
		_printMapAnyMessagePlural(build, vss)
	case [][]string:
		_printMapAnyMessagePlural(build, vs)
	case [][]any:
		// 测试是否能将[][]any 转为 [][]string
		vss := make([][]string, len(vs))
		for i, vvs := range vs {
			vss[i] = make([]string, len(vvs))
			for j, v := range vvs {
				switch vv := v.(type) {
				default:
					return
				case string:
					vss[i][j] = vv
				}
			}
		}
		_printMapAnyMessagePlural(build, vss)
	case map[string]any:
		build.WriteString("{\n")
		// 按Key排序后输出
		for _, k := range getSortedMapKeys(vs) {
			_printMapAnyMessage(build, k, vs[k], index+1)
		}
		if index > 0 {
			build.WriteString(strings.Repeat("...", index))
		}
		build.WriteString("}\n")
	case map[string]string:
		build.WriteString("{\n")
		// 按Key排序后输出
		for _, k := range getSortedMapKeys(vs) {
			_printMapAnyMessage(build, k, vs[k], index+1)
		}
		if index > 0 {
			build.WriteString(strings.Repeat("...", index))
		}
		build.WriteString("}\n")
	}
}
func _printMapAnyMessagePlural(build *strings.Builder, data [][]string) {
	build.WriteString("[")
	for i, v := range data {
		if i > 0 {
			build.WriteString(", ")
		}
		build.WriteString("[")
		for j, v := range v {
			if j > 0 {
				build.WriteString(", ")
			}
			build.WriteString("\"")
			build.WriteString(v)
			build.WriteString("\"")
		}
		build.WriteString("]")
	}
	build.WriteString("]")
	build.WriteRune('\n')
}

// bytesToString 将字节切片转换为字符串，避免额外的内存分配和拷贝操作
func bytesToString(data []byte) string {
	size := len(data)
	if size == 0 {
		return ""
	}
	return unsafe.String(unsafe.SliceData(data), size)
}

// clearAnySpace 清除字符串中的所有空白字符（包括空格、制表符等）
func clearAnySpace(s string) string {
	if len(s) < 1 {
		return s
	}
	var b strings.Builder
	b.Grow(len(s))
	for _, c := range s {
		switch c {
		case '\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0:
			continue
		default:
			b.WriteRune(c)
		}
	}
	return b.String()
}

// getSortedMapKeys 获取map的key列表，并按字符串排序返回，用于格式化输出时保持顺序一致
func getSortedMapKeys[T any | string | *Message](data map[string]T) []string {
	keys := make([]string, 0, len(data))
	for k := range data {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	return keys
}

// getFormatArgsCount 获取格式化字符串中%占位符个数
func getFormatArgsCount(format string) (count int) {
	n := len(format)
	for i := 0; i < n; {
		if format[i] == '%' {
			// 处理边界情况：单独的 %
			if i+1 >= n {
				count++
				break
			}
			// 处理转义 %%
			if format[i+1] == '%' {
				i += 2
				continue
			}

			// 处理位置参数（如 %[1]d）
			if i+2 < n && format[i+1] == '[' {
				// 跳过位置参数索引
				i += 2
				for i < n && format[i] != ']' {
					i++
				}
				if i < n && format[i] == ']' {
					i++ // 跳过 ]
				}
			}

			count++ // 有效参数计数
			i++     // 跳过 %
			// 跳过格式修饰符（标志、宽度、精度）
			for ; i < n && !unicode.IsLetter(rune(format[i])); i++ {
			}
			// 跳过动词字符（如 s/d/v）
			if i < n && unicode.IsLetter(rune(format[i])) {
				i++
			}
		} else {
			i++
		}
	}
	return
}

// getIndexArgsCount 依据Count参数index索引位置从一组 args ...any 获取 Count int 数值
//   - index: 索引位置，从1开始计数
func getIndexArgsCount(index uint8, args ...any) (int, bool) {
	if len(args) < int(index) {
		return 0, false
	}
	count := 0
	switch countVal := args[index-1].(type) {
	case int:
		count = countVal
	case int8:
		count = int(countVal)
	case int16:
		count = int(countVal)
	case int32:
		count = int(countVal)
	case int64:
		if count > math.MaxInt {
			count = math.MaxInt
		} else {
			count = int(countVal)
		}
	case uint:
		count = int(countVal)
	case uint8:
		count = int(countVal)
	case uint16:
		count = int(countVal)
	case uint32:
		count = int(countVal)
	case uint64:
		if count > math.MaxInt {
			count = math.MaxInt
		} else {
			count = int(countVal)
		}
	case float32:
		count = int(countVal)
	case float64:
		if count > math.MaxInt {
			count = math.MaxInt
		} else {
			count = int(countVal)
		}
	case string:
		if intVal, err := strconv.Atoi(countVal); err == nil {
			count = intVal
		} else {
			return 0, false
		}
	default:
		return 0, false
	}
	return count, true
}
